package com.ny.zmb.openapi.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ny.zmb.glxt.entity.PmStore;
import com.ny.zmb.glxt.service.IPmStoreService;
import com.ny.zmb.openapi.constant.PHPConstant;
import com.ny.zmb.openapi.constant.ResultConstant;
import com.ny.zmb.openapi.controller.entity.Result;
import com.ny.zmb.openapi.entity.*;
import com.ny.zmb.openapi.service.IPmMerchantService;
import com.ny.zmb.openapi.service.IPmUserWalletService;
import com.ny.zmb.openapi.service.PmUserWalletLogService;
import com.ny.zmb.openapi.service.PmWalletUserLogService;
import com.ny.zmb.openapi.util.DateUtil;
import com.ny.zmb.openapi.util.StringUtil;
import com.ny.zmb.openapi.ysutil.YsHttpUtil;
import com.ny.zmb.openapi.ysutil.base.EYinShengBase;
import com.ny.zmb.openapi.ysutil.common.ServiceEnum;
import com.ny.zmb.openapi.ysutil.common.YsPayConstant;
import com.ny.zmb.openapi.ysutil.from.*;
import com.ny.zmb.openapi.ysutil.publicInterface.QueryAmountReqCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * e-企通
 * <p>
 * 钱包相关
 */
@RequestMapping("/ys/wallet")
@RestController
@CrossOrigin
@Slf4j
public class YsWalletController extends EYinShengBase {


    @Resource
    private YsHttpUtil ysHttpUtil;
    @Resource
    private IPmUserWalletService pmUserWalletService;
    @Resource
    private IPmMerchantService pmMerchantService;
    @Resource
    private IPmStoreService pmStoreService;
    @Resource
    private PmUserWalletLogService userWalletLogService;
    @Resource
    private PmWalletUserLogService walletUserLogService;

    static List<String> baseList = Arrays.asList("freezeUncashAmount", "cashAmount", "freezeCashAmount", "uncashAmount");


    /**
     * 验证信息
     *
     * @param command
     * @return
     */
    @PostMapping("confirmVerify")
    public Result confirmVerify(@RequestBody ConfirmVerifyRequestCommand command){
       try {
           if (null == command){
               return Result.fail("参数不能为空");
           }
           JSONObject send = ysHttpUtil.send(ServiceEnum.CONFIRM_VERIFY, YsPayConstant.ENV_PRD,
                   MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.CONFIRM_VERIFY.getApiName(), command);
           JSONObject result = send.getJSONObject("bizResponseJson");
           String subCode = result.getString("subCode");
           if (!"COM000".equals(subCode)){
               return Result.fail(result.getString("subMsg"));
           }
           return Result.ok(result);
       }catch (Exception var){
           return Result.fail(var.getMessage());
       }
    }


    /**
     * 重发验证码
     * @param command
     * @return
     */
    @GetMapping("resendCode")
    public Result resendCode(ResendCodeReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.RESEND_CODE, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.RESEND_CODE.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 平台内转账-多笔
     *
     * @param command
     * @return
     */
    @PostMapping("batchTransferInner")
    public Result batchTransferInner(@RequestBody BatchTransferInnerReqCommand command){
        JSONArray batchList = command.getBatchList();
        command.setRequestNo(getUUID());
        JSONObject send = ysHttpUtil.send(ServiceEnum.TRANSFER_INNERBATCHQUERY, YsPayConstant.ENV_PRD,
                MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.TRANSFER_INNERBATCHQUERY.getApiName(), command);
        JSONObject result = send.getJSONObject("bizResponseJson");
        String subCode = result.getString("subCode");
        PmWalletUserLog walletUserLog = PmWalletUserLog.builder().build();
        walletUserLog.setBatchList(JSONObject.toJSONString(batchList));
        walletUserLog.setRequestNo(command.getRequestNo());
        Long time = System.currentTimeMillis() / 1000;
        walletUserLog.setCreatetime(time.intValue());
        walletUserLog.setPayerMerchantNo(command.getPayerMerchantNo());
        walletUserLog.setTotalAmount(command.getTotalAmount());
        walletUserLog.setTotalCount(command.getTotalCount());
        walletUserLog.setResultStatus(result.toJSONString());
        walletUserLogService.save(walletUserLog);
        if ("COM000".equals(subCode)){
            for (int i = 0 ; i < batchList.size() ; i++) {
                JSONObject batch = batchList.getJSONObject(i);
                String payeeMerchantNo = batch.getString("payeeMerchantNo");
                String orderDesc = batch.getString("orderDesc");
                BigDecimal amount = batch.getBigDecimal("amount");
                String subRequestNo = batch.getString("subRequestNo");
                if (payeeMerchantNo.startsWith("Y")){
                    LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
                    wrapper.eq(PmUserWallet::getWalletNo,payeeMerchantNo);
                    PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
                    PmUserWalletLog build= PmUserWalletLog.builder()
                            .money(amount)
                            .memo(orderDesc)
                            .tag(3)
                            .moneyType("money")
                            .targetId(command.getRequestNo()+"-"+subRequestNo)
                            .userId(one.getUserId())
                            .build();
                    this.userWalletLogService.addWalletLog(build);
                } else {
                    PmStore pmStore = pmStoreService.getInfoByBusinessNo(payeeMerchantNo);
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("merchantNo", payeeMerchantNo);
                    JSONObject returnResult = pmMerchantService.queryBalances(jsonObject);
                    BigDecimal totalAmount = returnResult.getBigDecimal("totalAmount") == null ? BigDecimal.ZERO : returnResult.getBigDecimal("totalAmount");
                    Integer userId = pmStore != null ? pmStore.getUserId() : null;
                    PmUserWalletLog build = PmUserWalletLog.builder()
                            .money(amount)
                            .memo(orderDesc)
                            .tag(3)
                            .moneyType("merchant")
                            .targetId(command.getRequestNo() + "-" + subRequestNo)
                            .userId(userId)
                            .beforeMoney(totalAmount)
                            .afterMoney(totalAmount.add(amount))
                            .createtime(time.intValue())
                            .build();
                    this.userWalletLogService.addMerchantWalletLog(build);
                }
            }
            return Result.ok(result);
        }
        return Result.fail(result.getString("subMsg"));
    }

    /**
     * 平台内转账-多笔
     * @param command
     * @return
     */
    @PostMapping("accountSeqQuery")
    public Result accountSeqQuery(@RequestBody AccountSeqQueryReqCommand command){
        command.setSrcMerchantNo(SRC_MERCHANT_NO);
        JSONObject send = ysHttpUtil.sendBase(ServiceEnum.ACCOUNT_SEQQUERY, YsPayConstant.ENV_PRD,
                MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.ACCOUNT_SEQQUERY.getApiName(),SRC_MERCHANT_NO, command);
        return Result.ok(send);
    }

    /**
     * 平台内转账
     * @param command
     * @return
     */
    @PostMapping("transferInner")
    public Result transferInner(@RequestBody TransferInnerReqCommand command){
        command.setRequestNo(getUUID());
        JSONObject send = ysHttpUtil.send(ServiceEnum.BATCHTRANSFER_INNER, YsPayConstant.ENV_PRD,
                MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.BATCHTRANSFER_INNER.getApiName(), command);
        JSONObject result = send.getJSONObject("bizResponseJson");
        String subCode = result.getString("subCode");
        if (!"COM000".equals(subCode)){
            return Result.fail(result.getString("subMsg"));
        }
        return Result.ok(result);
    }
    /**
     * 余额查询
     * @return
     */
    @GetMapping("/person/queryBalance")
    public Result queryBalance(){
        try {
            LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(PmUserWallet::getUserId,getUserToken().getUserId());
            PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
            if (null == one){
                return Result.fail("暂无信息");
            }
            QueryAmountReqCommand reqCommand = new QueryAmountReqCommand();
            reqCommand.setMerchantNo(one.getWalletNo());
            JSONObject send = ysHttpUtil.send(ServiceEnum.QUERY_AMOUNT, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.QUERY_AMOUNT.getApiName(), reqCommand);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            JSONArray accountList = result.getJSONArray("accountList");
            List<JSONObject> jsonObjects = accountList.toJavaList(JSONObject.class);
            JSONObject jsonObject = jsonObjects.get(0);
            Set<String> strings = jsonObject.keySet();
            for (String key :strings){
                BigDecimal re = BigDecimal.ZERO;
                for (JSONObject json : jsonObjects) {
                    if (baseList.contains(key)){
                        BigDecimal bigDecimal = json.getBigDecimal(key);
                        re = re.add(bigDecimal);
                    }
                }
                result.put(key,re);
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }
    /***
     * 账户余额查询-个人
     * @return
     */
    @GetMapping("/person/userInfo")
    public Result userInfo(){
        try {
            LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(PmUserWallet::getUserId,getUserToken().getUserId());
            PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
            if (null == one){
                JSONObject  result = new JSONObject();
                result.put("registerStatus",false);
                return Result.ok(result);
            }
            QueryAmountReqCommand reqCommand = new QueryAmountReqCommand();
            reqCommand.setMerchantNo(one.getWalletNo());
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_USER_INFO, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_USER_INFO.getApiName(), reqCommand);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            result.put("registerStatus",true);
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包注册-个人
     * @param command
     * @return
     */
    @PostMapping("/person/walletRegister")
    public Result walletRegister(@RequestBody WalletRegisterReqCommand command){
        try {
            PmUserToken userToken = getUserToken();
            Integer userId = userToken.getUserId();
            if (null == command && null != userId){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_REGISTER, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_REGISTER.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (ResultConstant.subCode.equals(subCode)){
                LambdaQueryWrapper<PmUserWallet> lambdaQuery = Wrappers.lambdaQuery();
                lambdaQuery.eq(PmUserWallet::getUserId,userId);
                List<PmUserWallet> list = this.pmUserWalletService.list(lambdaQuery);
                if (null != list || list.size() > 0){
                    return Result.fail("您已注册成功");
                }
                Long now  = System.currentTimeMillis() / 1000;
                PmUserWallet wallet = PmUserWallet.builder()
                        .createTime(now.intValue())
                        .userId(userId)
                        .walletNo(result.getString("merchantNo"))
                        .build();
                this.pmUserWalletService.save(wallet);
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包提现-个人
     * @param command
     * @return
     */
    @PostMapping("/person/withdraw")
    public Result withdraw(@RequestBody WithdrawReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            PmUserToken userToken = getUserToken();
            command.setRequestNo(getUUID());
            LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(PmUserWallet::getUserId,userToken.getUserId());
            PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
            command.setRequestNo(getUUID());
            command.setMerchantNo(one.getWalletNo());
            command.setNotifyUrl(PHPConstant.JAVA_BASE_URL + "/ys/wallet/notifyWallet");
            if (StringUtil.isBlank(command.getRemark())){
                command.setRemark("钱包提现");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_WITHDRAW, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_WITHDRAW.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包绑卡-个人
     * @param command
     * @return
     */
    @PostMapping("/person/bindCard")
    public Result bindCard(@RequestBody BindCardReqCommand command){

        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            command.setRequestNo(getUUID());
            command.setBindFunction("01");
            LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(PmUserWallet::getUserId,getUserToken().getUserId());
            PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
            if (null ==  one){
                throw new RuntimeException("你还未注册钱包！");
            }
            command.setMerchantNo(one.getWalletNo());
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_BIND_CARD, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_BIND_CARD.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包解绑-个人
     * @param command
     * @return
     */
    @PostMapping("/person/unbind")
    public Result unbind(@RequestBody UnBindReqCommand command) {
        try {
            if (null == command) {
                return Result.fail("参数不能为空");
            }
            command.setRequestNo(getUUID());
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_UNBIND, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_UNBIND.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包身份证照片补充-个人
     * @param command
     * @return
     */
    @PostMapping("/person/supplyCardPic")
    public Result withdraw(@RequestBody SupplyCardPicReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_SUPPLY_CARD_PIC, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_SUPPLY_CARD_PIC.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }


    /**
     * 钱包账户充值-个人
     * @param command
     * @return
     */
    @PostMapping("/person/recharge")
    public Result recharge(@RequestBody RechargeReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_RECHARGE, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_RECHARGE.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包消费-个人
     * @param command
     * @return
     */
    @PostMapping("/person/consume")
    public Result consume(@RequestBody ConsumeReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_CONSUME, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_CONSUME.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }


    /**
     * 钱包账单查询-个人
     * @param command
     * @return
     */
    @GetMapping("/person/queryWalletBill")
    public Result queryWalletBill(QueryWalletBillReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            command.setSrcMerchantNo(SRC_MERCHANT_NO);
            JSONObject send = ysHttpUtil.sendBase(ServiceEnum.QUERY_WALLETBILL, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.QUERY_WALLETBILL.getApiName(),SRC_MERCHANT_NO, command);
            return Result.ok(send);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }

    /**
     * 钱包订单查询-个人
     * @param command
     * @return
     */
    @GetMapping("/person/queryOrder")
    public Result queryOrder(QueryOrderReqCommand command){
        return this.queryOrders(command);
    }

    @RequestMapping(value = "notifyWallet",consumes = "application/x-www-form-urlencoded")
    public String notifyWallet(HttpServletResponse response, HttpServletRequest request){
        try {
            String bizResponseJson = request.getParameter("bizResponseJson");
            bizResponseJson = bizResponseJson.replaceAll("\\\\","");
            JSONObject biz = JSONObject.parseObject(bizResponseJson);
            String requestNo = biz.getString("requestNo");
            QueryOrderReqCommand reqCommand = new QueryOrderReqCommand();
            reqCommand.setRequestNo(requestNo);
            Result result = this.queryOrder(reqCommand);
            JSONObject jsonResult = (JSONObject)result.getData();
            JSONObject withdrawInfo = jsonResult.getJSONObject("withdrawInfo");
            if (null != withdrawInfo){
                String merchantNo = withdrawInfo.getString("merchantNo");
                LambdaQueryWrapper<PmUserWallet> wrapper = Wrappers.lambdaQuery();
                wrapper.eq(PmUserWallet::getWalletNo,merchantNo);
                PmUserWallet one = this.pmUserWalletService.getOne(wrapper);
                PmUserWalletLog build= PmUserWalletLog.builder()
                        .money(biz.getBigDecimal("amount").multiply(BigDecimal.valueOf(-1)))
                        .memo("钱包提现(含手续费1元)")
                        .tag(3)
                        .moneyType("money")
                        .targetId(requestNo)
                        .userId(one.getUserId())
                        .build();
                this.userWalletLogService.addWalletLog(build);
            }
        }catch (Exception var){
            log.error(var.getMessage());
            return "success";
        }

        return "success";
    }

    /**
     *
     * @return
     */
    private static String getUUID(){
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return uuid.substring(uuid.length() - 15);
    }

    private Result queryOrders(QueryOrderReqCommand command){
        try {
            if (null == command){
                return Result.fail("参数不能为空");
            }
            JSONObject send = ysHttpUtil.send(ServiceEnum.WALLET_QUERY_ORDER, YsPayConstant.ENV_PRD,
                    MERCHANT_PRX, MERCHANT_PRX_PWD,ServiceEnum.WALLET_QUERY_ORDER.getApiName(), command);
            JSONObject result = send.getJSONObject("bizResponseJson");
            String subCode = result.getString("subCode");
            if (!"COM000".equals(subCode)){
                return Result.fail(result.getString("subMsg"));
            }
            return Result.ok(result);
        }catch (Exception var){
            return Result.fail(var.getMessage());
        }
    }
}
